#nullable enable
using Godot;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AndroidUnevenRoadGame.Game;

namespace AndroidUnevenRoadGame.UI
{
	public partial class BattleScene : Control
	{
		private static readonly Vector2 PortraitSize = new Vector2(64, 64);
		private const string DefaultCardTitle = "卡牌详情";
		private const string DefaultCardDescription = "将鼠标移动到手牌按钮上方以查看效果描述。";

		[Export] private Label? _playerInfo;
		[Export] private Label? _enemyInfo;
		[Export] private ItemList? _logList;
		[Export] private Button? _endTurnButton;
		[Export] private HBoxContainer? _handContainer;
		[Export] private TextureRect? _playerPortrait;
		[Export] private TextureRect? _enemyPortrait;
		[Export] private Label? _enemyTargetsLabel;
		[Export] private HBoxContainer? _enemyTargetsContainer;
		[Export] private AudioStreamPlayer? _bgmPlayer;
		[Export] private AudioStreamPlayer? _sfxPlayer;
		[Export] private Label? _cardTitleLabel;
		[Export] private RichTextLabel? _cardDescriptionLabel;

		private int _selectedEnemyIndex = -1;

		private static readonly Dictionary<string, string> SfxPaths = new()
		{
			["card_use"] = "res://Assets/Audio/SFX/card_use.mp3",
			["hit"] = "res://Assets/Audio/SFX/hit_sound.mp3",
			["death"] = "res://Assets/Audio/SFX/enemy_death.mp3",
			["crit"] = "res://Assets/Audio/SFX/crit_sound.mp3"
		};

		private const string BattleBgmPath = "res://Assets/Audio/Music/battle_background_music01.mp3";

		public override void _Ready()
		{
			_playerInfo ??= GetNodeOrNull<Label>("Content/MainColumn/PlayerInfo");
			_enemyInfo ??= GetNodeOrNull<Label>("Content/MainColumn/EnemyInfo");
			_logList ??= GetNodeOrNull<ItemList>("Content/MainColumn/LogList");
			_handContainer ??= GetNodeOrNull<HBoxContainer>("Content/MainColumn/HandContainer");
			_playerPortrait ??= GetNodeOrNull<TextureRect>("Content/PortraitRow/PlayerPortrait");
			_enemyPortrait ??= GetNodeOrNull<TextureRect>("Content/PortraitRow/EnemyPortrait");
			_enemyTargetsLabel ??= GetNodeOrNull<Label>("Content/MainColumn/EnemyTargetsLabel");
			_enemyTargetsContainer ??= GetNodeOrNull<HBoxContainer>("Content/MainColumn/EnemyTargets");
			_bgmPlayer ??= GetNodeOrNull<AudioStreamPlayer>("BgmPlayer");
			_sfxPlayer ??= GetNodeOrNull<AudioStreamPlayer>("SfxPlayer");
			_endTurnButton ??= GetNodeOrNull<Button>("Content/MainColumn/EndTurnButton");
			_cardTitleLabel ??= GetNodeOrNull<Label>("Content/CardInfoPanel/CardInfoMargin/CardInfoBox/CardTitle");
			_cardDescriptionLabel ??= GetNodeOrNull<RichTextLabel>("Content/CardInfoPanel/CardInfoMargin/CardInfoBox/CardDescription");

			ConfigurePortrait(_playerPortrait);
			ConfigurePortrait(_enemyPortrait);
			ResetCardDetails();

			if (_endTurnButton != null)
			{
				_endTurnButton.Pressed += OnEndTurnPressed;
			}

			var game = GameRoot.Instance;
			game.StateChanged += OnGameStateChanged;

			UpdateUI();
		}

		private static void ConfigurePortrait(TextureRect? rect)
		{
			if (rect == null)
			{
				return;
			}

			rect.CustomMinimumSize = PortraitSize;
			rect.Size = PortraitSize;
			rect.StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered;
			rect.SizeFlagsHorizontal = Control.SizeFlags.ShrinkCenter;
			rect.SizeFlagsVertical = Control.SizeFlags.ShrinkCenter;
		}

		public override void _ExitTree()
		{
			if (!Engine.IsEditorHint() && GameRoot.Instance != null)
			{
				GameRoot.Instance.StateChanged -= OnGameStateChanged;
			}
			StopBgm();
		}

		private void OnEndTurnPressed()
		{
			GameRoot.Instance.BattleManager.EndPlayerTurn();
			PlaySfx("hit");
			UpdateUI();
		}

		private void OnGameStateChanged(int stateValue)
		{
			var state = (GameRoot.GameState)stateValue;
			Visible = state == GameRoot.GameState.Battle;
			if (Visible)
			{
				UpdateUI();
				EnsureBgm();
			}
			else
			{
				StopBgm();
			}
		}

		private void UpdateUI()
		{
			var game = GameRoot.Instance;
			var player = game.Player;

			EnsureBgm();

			if (_playerInfo != null)
			{
				_playerInfo.Text = $"玩家生命：{player.CurrentHp}/{player.MaxHp}  格挡：{player.Block}  能量：{player.CurrentEnergy}/{player.EnergyPerTurn}";
			}

			if (_enemyInfo != null)
			{
				var sb = new StringBuilder();
				int index = 1;
				foreach (var enemy in game.BattleManager.Enemies)
				{
					var damageText = enemy.MinDamage == enemy.MaxDamage
						? enemy.MinDamage.ToString()
						: $"{enemy.MinDamage}-{enemy.MaxDamage}";
					sb.AppendLine($"[{index}] {enemy.Definition.Name}（{GetCategoryLabel(enemy.Definition.Category)}）: {enemy.CurrentHp}/{enemy.MaxHp} HP  预计伤害：{damageText}");
					index++;
				}
				_enemyInfo.Text = sb.ToString().TrimEnd();
			}

			RenderHand();
			RenderLog();
			RenderEnemyTargets();
			UpdatePortraits();
		}

		private void ResetCardDetails()
		{
			if (_cardTitleLabel != null)
			{
				_cardTitleLabel.Text = DefaultCardTitle;
			}

			if (_cardDescriptionLabel != null)
			{
				_cardDescriptionLabel.Text = DefaultCardDescription;
			}
		}

		private void ShowCardDetails(CardDefinition card)
		{
			if (_cardTitleLabel != null)
			{
				_cardTitleLabel.Text = $"{card.Name}｜{GetCardTypeLabel(card.Type)}｜能量 {card.Cost}";
			}

			if (_cardDescriptionLabel != null)
			{
				_cardDescriptionLabel.Text = string.IsNullOrWhiteSpace(card.Description)
					? "（该卡牌暂无描述）"
					: card.Description;
			}
		}

		private static string GetCardTypeLabel(CardType type)
		{
			return type switch
			{
				CardType.Attack => "攻击",
				CardType.Skill => "技能",
				CardType.Power => "能力",
				CardType.Status => "状态",
				CardType.Curse => "诅咒",
				_ => type.ToString()
			};
		}

		private void RenderHand()
		{
			if (_handContainer == null)
			{
				return;
			}

			foreach (Node child in _handContainer.GetChildren())
			{
				child.QueueFree();
			}

			var game = GameRoot.Instance;
			var player = game.Player;

			ResetCardDetails();

			foreach (var cardId in player.Hand.ToList())
			{
				var card = CardDatabase.Get(cardId);
				var button = new Button
				{
					Text = $"{card.Name}\n能量:{card.Cost}",
					SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
					SizeFlagsVertical = Control.SizeFlags.ShrinkCenter,
					Disabled = card.Cost > player.CurrentEnergy
				};

				var cardIdCopy = cardId;
				var cardDefinition = card;
				button.TooltipText = $"{cardDefinition.Name}（{GetCardTypeLabel(cardDefinition.Type)}，能量 {cardDefinition.Cost}）\n{cardDefinition.Description}";
				button.Pressed += () => OnCardPressed(cardIdCopy);
				button.MouseEntered += () => ShowCardDetails(cardDefinition);
				button.MouseExited += ResetCardDetails;
				button.FocusEntered += () => ShowCardDetails(cardDefinition);
				button.FocusExited += ResetCardDetails;
				_handContainer.AddChild(button);
			}

			if (player.Hand.Count == 0)
			{
				var placeholder = new Label
				{
					Text = "（当前无手牌）",
					SizeFlagsHorizontal = Control.SizeFlags.ExpandFill,
					HorizontalAlignment = HorizontalAlignment.Center
				};
				_handContainer.AddChild(placeholder);
			}
		}

		private void RenderLog()
		{
			if (_logList == null)
			{
				return;
			}

			_logList.Clear();
			foreach (var entry in GameRoot.Instance.BattleManager.BattleLog)
			{
				_logList.AddItem(entry);
			}

			if (_logList.ItemCount > 0)
			{
				_logList.Select(_logList.ItemCount - 1);
				_logList.EnsureCurrentIsVisible();
			}
		}

		private void OnCardPressed(string cardId)
		{
			var manager = GameRoot.Instance.BattleManager;
			var card = CardDatabase.Get(cardId);
			EnemyState? target = null;

			if (card.Type == CardType.Attack)
			{
				target = GetSelectedEnemy();
				if (target == null)
				{
					manager.BattleLog.Add("请选择一个攻击目标。");
					RenderLog();
					return;
				}
			}

			manager.PlayCard(cardId, target);
			PlaySfx("card_use");
			UpdateUI();
		}

		private void UpdatePortraits()
		{
			if (_playerPortrait != null)
			{
				var playerPortraitTexture = LoadTexture(GameRoot.Instance.Player.Character.PortraitPath);
				_playerPortrait.Texture = playerPortraitTexture;
				_playerPortrait.Visible = playerPortraitTexture != null;
			}

			if (_enemyPortrait != null)
			{
				var target = GetSelectedEnemy()
							 ?? GameRoot.Instance.BattleManager.Enemies.FirstOrDefault(enemy => !enemy.IsDead)
							 ?? GameRoot.Instance.BattleManager.Enemies.FirstOrDefault();
				var enemyPortraitTexture = target != null ? LoadTexture(target.Definition.PortraitPath) : null;
				_enemyPortrait.Texture = enemyPortraitTexture;
				_enemyPortrait.Visible = enemyPortraitTexture != null;
			}
		}

		private static Texture2D? LoadTexture(string path)
		{
			if (string.IsNullOrEmpty(path))
			{
				return null;
			}

			return ResourceLoader.Exists(path) ? ResourceLoader.Load<Texture2D>(path) : null;
		}

		private void EnsureBgm()
		{
			if (_bgmPlayer == null)
			{
				return;
			}

			if (_bgmPlayer.Stream == null)
			{
				if (ResourceLoader.Exists(BattleBgmPath))
				{
					_bgmPlayer.Stream = ResourceLoader.Load<AudioStream>(BattleBgmPath);
				}
			}

			if (_bgmPlayer.Stream != null && !_bgmPlayer.Playing)
			{
				_bgmPlayer.Play();
			}
		}

		private void StopBgm()
		{
			if (_bgmPlayer != null && _bgmPlayer.Playing)
			{
				_bgmPlayer.Stop();
			}
		}

		private void PlaySfx(string key)
		{
			if (_sfxPlayer == null)
			{
				return;
			}

			if (!SfxPaths.TryGetValue(key, out var path) || !ResourceLoader.Exists(path))
			{
				return;
			}

			var stream = ResourceLoader.Load<AudioStream>(path);
			if (stream != null)
			{
				_sfxPlayer.Stream = stream;
				_sfxPlayer.Play();
			}
		}

		private void RenderEnemyTargets()
		{
			if (_enemyTargetsContainer == null)
			{
				return;
			}

			foreach (Node child in _enemyTargetsContainer.GetChildren())
			{
				child.QueueFree();
			}

			var enemies = GameRoot.Instance.BattleManager.Enemies;
			EnsureSelectedEnemy(enemies);

			if (_enemyTargetsLabel != null)
			{
				_enemyTargetsLabel.Visible = enemies.Count > 1;
			}

			for (int i = 0; i < enemies.Count; i++)
			{
				var enemy = enemies[i];
				var button = new Button
				{
					Text = $"{i + 1}. {enemy.Definition.Name}\n{enemy.CurrentHp}/{enemy.MaxHp} HP",
					Disabled = enemy.IsDead
				};

				var baseColor = enemy.IsDead ? Colors.DarkSlateGray : Colors.White;
				var displayColor = i == _selectedEnemyIndex ? Colors.Gold : baseColor;

				button.AddThemeColorOverride("font_color", displayColor);
				button.AddThemeColorOverride("font_color_hover", displayColor);
				button.AddThemeColorOverride("font_color_pressed", displayColor);

				var indexCopy = i;
				button.Pressed += () => OnEnemySelected(indexCopy);

				_enemyTargetsContainer.AddChild(button);
			}
		}

		private void OnEnemySelected(int index)
		{
			var enemies = GameRoot.Instance.BattleManager.Enemies;
			if (index < 0 || index >= enemies.Count)
			{
				return;
			}

			if (enemies[index].IsDead)
			{
				return;
			}

			_selectedEnemyIndex = index;
			RenderEnemyTargets();
			UpdatePortraits();
		}

		private void EnsureSelectedEnemy(IReadOnlyList<EnemyState> enemies)
		{
			if (enemies.Count == 0)
			{
				_selectedEnemyIndex = -1;
				return;
			}

			if (_selectedEnemyIndex >= 0 && _selectedEnemyIndex < enemies.Count && !enemies[_selectedEnemyIndex].IsDead)
			{
				return;
			}

			for (int i = 0; i < enemies.Count; i++)
			{
				if (!enemies[i].IsDead)
				{
					_selectedEnemyIndex = i;
					return;
				}
			}

			_selectedEnemyIndex = -1;
		}

		private EnemyState? GetSelectedEnemy()
		{
			var enemies = GameRoot.Instance.BattleManager.Enemies;
			EnsureSelectedEnemy(enemies);

			if (_selectedEnemyIndex >= 0 && _selectedEnemyIndex < enemies.Count)
			{
				var enemy = enemies[_selectedEnemyIndex];
				return enemy.IsDead ? null : enemy;
			}

			return null;
		}

		private static string GetCategoryLabel(EnemyCategory category)
		{
			return category switch
			{
				EnemyCategory.Elite => "精英",
				EnemyCategory.Boss => "首领",
				_ => "普通"
			};
		}
	}
}

